package 方法的抽象和逐步求精;

import java.util.Scanner;

public class printCalendar {
	/** main method */
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.print("请输入年份: ");
		int year = input.nextInt();
		System.out.print("请输入月份 1 至 12: ");
		int month = input.nextInt();
		printMonth(year, month);
	}
	/**打印日历*/
	public static void printMonth(int year,int month){
		printMonthTitle(year, month);
		printMonthBody(year, month);
	}
	
	/**打印日历头信息*/
	public static void printMonthTitle(int year,int month){
		System.out.println("     "+year +""+ getMonthName(month));
		System.out.println("---------------------------------");
		System.out.println("星期天 星期一 星期二 星期三 星期四 星期五 星期六");
	}
	/**
	 * 打印日历主体
	 * @param year
	 * @param month
	 */
	public static void printMonthBody(int year,int month){
		int startDay = getStartDay(year, month);
 		int numberOfDaysInMonth = getNumberOfDaysInMonth(year, month);
		
		for(int i = 0;i < startDay;i++)
			System.out.print("     ");
		for(int i =1;i <= numberOfDaysInMonth;i++){
			System.out.printf("%4d",i);
			
			if((i + startDay) % 7 == 0)
				System.out.println();
		}
		
		System.out.println();
	}
	
	/**
	 * 获取月份数字对应的字符
	 * @param month
	 * @return
	 */
	public static String getMonthName(int month){
		String monthName = " ";
		switch (month) {
			case 1: monthName = "January";break;
			case 2: monthName = "February";break;
			case 3: monthName = "March";break;
			case 4: monthName = "April";break;
			case 5: monthName = "May";break;
			case 6: monthName = "June";break;
			case 7: monthName = "July";break;
			case 8: monthName = "August";break;
			case 9: monthName = "September";break;
			case 10: monthName = "October";break;
			case 11: monthName = "November";break;
			case 12: monthName = "December";break;
		}
		return monthName;
	}
	
	/** 当前月份开始一天是星期几 */
	public static int getStartDay(int year,int month){
		final int START_DAY_FOR_JAN_1_1800 = 3;
		
		int totalNumberOfDays = getTotalNumberOfDays(year, month);
		// Return the start day for month/1year 返回起始日期 
		return (totalNumberOfDays + START_DAY_FOR_JAN_1_1800) % 7;
	}
	/** 得到1800年至今的总天数 */
	public static int getTotalNumberOfDays(int year,int month){
		int total = 0;
		// Get the total days from 1800 to 1/1/year 
		for(int i = 1800;i < year;i++){
			if(isLeapYear(i))
				total = total + 366;
			else
				total = total + 365;
		}
		// Add days from jan to the month prior to the calendar month 
		// 1/1 to this month 一月一日到当前月份
		for(int i = 1;i < month;i++){
			total = total + getNumberOfDaysInMonth(year, i);
		}
		return total;
	}
	
	/** 获取当前年份的当前月份有多少天*/
	public static int getNumberOfDaysInMonth(int year,int month){
		if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || 
				month == 10 || month == 12)
			return 31;
		if(month == 4 || month == 6 || month == 9 || month == 11)
			return 30;
		if(month == 2)
			return isLeapYear(year) ? 29 : 28;
					
		return 0;
	}
	
	/**  判断是否是闰年 */
	public static boolean isLeapYear(int year){
		return year % 400 ==0 || (year % 4 == 0 && year % 100 != 0);
	}
}
